<?php
/**
 * Navigation class
 * This class can be used for printing multi-level navigation components such as vertical menu
 * or hoziron menu. Two or more instances of navigation components can be registered
 *
 * @package OWL
 * @subpackage Helper
 * @author KeiMOon
 * @since 1.0
 */

class Owl_Navigation {
//Navigation handles
    private $_navigation_handle;

    /**
     * Singleton instance
     *
     * @var Navigation
     */
    private static $_instance;

    /**
     * This constructor is private because this class is singleton
     *
     * @return true
     */
    private function  __construct() {
        return true;
    }

    /**
     * Clone method is private because this class is singleton
     *
     * @return true
     */
    private function  __clone() {
        return true;
    }

    /**
     * Use this method for initializing object instead of new operator.
     *
     * @return Navigation Navigation singleton instance
     */
    static function get_instance() {
        if( self::$_instance === NULL ) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }

    /**
     * Register a menu to a navigation handle
     *
     * @param string $handle
     * @param string $menu_id Must be unique in a handle
     * @param string $anchor_text
     * @param string $anchor_link
     * @param string|bool $parent Default value is false (first-level element)
     */
    function register_menu($handle, $menu_id, $anchor_text, $anchor_link, $parent = false) {
        if ((isset($this->_navigation_handle[$handle])) && array_key_exists($menu_id, $this->_navigation_handle[$handle])) {
            return false;
        }
        if ($parent !== false) {
            if ($menu_id == $parent || !array_key_exists($parent, $this->_navigation_handle[$handle])) {
                return false;
            }
        }
        $this->_navigation_handle[$handle][$menu_id] = array(
            "anchor_text" => $anchor_text,
            "anchor_link" => $anchor_link,
            "parent" => $parent
        );
    }

    /**
     * Print a navigation handle
     *
     * @param string $handle
     * @param string $current_id
     * @return false if the handle does not exist
     */
    function print_navigation_handle($handle, $current_id) {
        if (!is_array($this->_navigation_handle[$handle])) {
            return false;
        }
        echo "<div class=\"navigation\">\n";
        $this->walk($handle, $current_id);
        echo "</div>\n";
    }

    private function walk($handle, $current_id, $depth = 0, $parent = false) {
        if ($parent === false) {
            $children = $this->get_first_level_elements($handle);
        }
        else {
            $children = $this->get_children($handle, $parent);
        }
        if ($depth == 0) {
            echo "<ul class=\"navigation-container-root\">\n";
        }
        else {
            $repeat = str_repeat("\t", $depth);
            $menu_data = $this->_navigation_handle[$handle][$parent];
            if ($this->get_children($handle, $parent) !== false) {
                if ($current_id == $parent) {
                    echo "$repeat<li class=\"navigation-menu has-children\">\n";
                    if ($menu_data["anchor_link"]) {
                        echo "$repeat\t<a href=\"" . $menu_data["anchor_link"] . "\" class=\"current\" id=\"navigation-" . $parent . "\"><span>".$menu_data["anchor_text"]."</span></a>\n";
                    }
                    else {
                        echo $menu_data["anchor_text"];
                    }
                }
                else {
                    echo "$repeat<li class=\"navigation-menu has-children\">\n";
                    if ($menu_data["anchor_link"]) {
                        echo "$repeat\t<a href=\"" . $menu_data["anchor_link"] . "\" id=\"navigation-" . $parent . "\"><span>".$menu_data["anchor_text"]."</span></a>\n";
                    }
                    else {
                        echo $menu_data["anchor_text"];
                    }
                }
                echo "$repeat\t<ul class=\"navigation-container level-$depth\">\n";
            }
            else {
                if ($current_id == $parent) {
                    if ($menu_data["anchor_link"]) {
                        echo "$repeat<li class=\"navigation-menu\"><a href=\"" . $menu_data["anchor_link"] . "\" class=\"current\" id=\"navigation-" . $parent . "\"><span>".$menu_data["anchor_text"]."</span></a></li>\n";
                    }
                    else {
                        echo "$repeat<li class=\"navigation-menu\">".$menu_data["anchor_text"]."</li>\n";
                    }
                }
                else {
                    if ($menu_data["anchor_link"]) {
                        echo "$repeat<li class=\"navigation-menu\"><a href=\"" . $menu_data["anchor_link"] . "\" id=\"navigation-" . $parent . "\"><span>".$menu_data["anchor_text"]."</span></a></li>\n";
                    }
                    else {
                        echo "$repeat<li class=\"navigation-menu\">".$menu_data["anchor_text"]."</li>\n";
                    }
                }
            }
        }        
        if ($children !== false) {
            foreach ($children as $child) {
                $this->walk($handle, $current_id, $depth + 1, $child);
            }
        }
        if ($this->get_children($handle, $parent) !== false) {
            echo "$repeat\t</ul>\n$repeat</li>\n";
        }
        if ($depth == 0) {
            echo "</ul>\n";
        }
    }

    private function get_first_level_elements($handle) {
        $result = array();
        foreach ($this->_navigation_handle[$handle] as $menu_id => $menu_data) {
            if ($menu_data["parent"] === false) {
                $result[] = $menu_id;
            }
        }
        return $result;
    }

    private function get_children($handle, $parent_id) {
        if (!is_array($this->_navigation_handle[$handle][$parent_id])) {
            return false;
        }
        $children = array();
        foreach ($this->_navigation_handle[$handle] as $menu_id => $menu_data) {
            if ($menu_data["parent"] == $parent_id) {
                $children[] = $menu_id;
            }
        }
        return (empty($children)) ? false : $children;
    }
}

//Register default navigation
$navigation = Owl_Navigation::get_instance();

$navigation->register_menu("site-navigation", "note", __("Note"), Owl_Link::template_url("note", false));
$navigation->register_menu("site-navigation", "info", __("Personal info"), Owl_Link::template_url("info", false));
$navigation->register_menu("site-navigation", "product", __("Products"), Owl_Link::template_url("product", false));
$navigation->register_menu("site-navigation", "pages-list", __("Pages list"), Owl_Link::template_url("pages-list", false));
$navigation->register_menu("site-navigation", "course", __("Courses"), Owl_Link::template_url("course", false));

$navigation->register_menu("setting-navigation", "add-page", __("Add page"), Owl_Link::template_url("add-page", false));
$navigation->register_menu("setting-navigation", "pages-manager", __("Pages"), Owl_Link::template_url("pages-manager", false));
$navigation->register_menu("setting-navigation", "documents-manager", __("Documents"), Owl_Link::template_url("documents-manager", false));
$navigation->register_menu("setting-navigation", "system-options", __("System"), Owl_Link::template_url("system-options", false));
$navigation->register_menu("setting-navigation", "themes-manager", __("Themes"), Owl_Link::template_url("themes-manager", false));
$navigation->register_menu("setting-navigation", "widgets-manager", __("Widgets"), Owl_Link::template_url("widgets-manager", false));
$navigation->register_menu("setting-navigation", "password", __("Password"), Owl_Link::template_url("password", false));
